/*
 * @Author: 我想吃余 483766615@qq.com
 * @Date: 2025-11-18 20:37:29
 * @LastEditors: 我想吃余 483766615@qq.com
 * @LastEditTime: 2025-11-18 21:11:51
 * @FilePath: /code/oscode/thread_pool/ThreadPollV3.hpp
 * @Description: 设置为单例模式的懒汉模式，延迟加载以提升效率
 */
#pragma once

#include <iostream>
#include <vector>
#include <string>
#include <pthread.h>
#include "Thread.hpp"
#include "task.hpp"
#include "block_queue.hpp"

#define NUM 10

template<class T>
class threadpool
{
private:
     std::string GetName(pthread_t tid)
     {
          for(auto &t : _threads)
          {
               if(t.GetTid() == tid)
                    return t.GetName();
          }
          return "None!";
     }

     // 处理任务（消费任务），线程池线程完成
     T Pop()
     {
          T t = _bq.pop();
          return t;
     }
public:
     // 实例化线程池的线程对象（注意此时线程还并未真正创建，需要start启动）
     void Init()
     {
          for(int i = 0; i < _num; ++i)
               _threads.push_back(Thread(i, HandlerTask, this));
     }

     // 线程的入口函数
     static void HandlerTask(void* args)
     {
          // 分离线程
          pthread_detach(pthread_self());

          threadpool<T> *tp = static_cast<threadpool<T> *>(args);
          std::string name = tp->GetName(pthread_self());
          while(true)
          {
               //消费任务
               Task t = tp->Pop();
               //处理任务
               t();
               std::cout << name << "处理任务：" << t.GetTask() << " 结果为：" << t.GetResult() << std::endl;
          }
     }

     void Start()//启动线程池，准备就绪
     {
          for(int i = 0; i < _num; ++i)
               _threads[i].Run();
     }

     // 添加任务(生产任务)，主线程完成
     void Push(const T &task)
     {
          _bq.push(task);
     }
     
     static threadpool<T>* GetInstance(int num)
     {
        // 双重判断，避免过多的线程前去申请锁，提升效率
        if(_tp == nullptr)
        {
            //加锁，防止并发条件下可能new出多个对象
            pthread_mutex_lock(&_mutex);
            if(_tp == nullptr)
            {
               std::cout << "log: singleton create done first!" << std::endl;
               _tp = new threadpool<T>(num);
            }
            pthread_mutex_unlock(&_mutex);
        }
        return _tp;
     }
private:
     // 禁用一切可能创建多余对象的函数
    threadpool(int num = NUM)
     :_num(num)
    {}
    threadpool(const threadpool<T> &) = delete;
    const threadpool<T> &operator=(const threadpool<T> &) = delete;
    ~threadpool()
    {}
private:
     std::vector<Thread> _threads;       // 线程池
     int _num;                           // 线程池的线程数量
     block_queue<T> _bq;                 // 基于阻塞队列的生产者消费者模型
     static threadpool<T> *_tp;          // 单例对象指针
     static pthread_mutex_t _mutex;      // 单例对象也属于共享资源，创建对象时需要加锁保护
};

// 静态成员变量需要类外初始化
template<class T>
threadpool<T>* threadpool<T>::_tp = nullptr;

template<class T>
pthread_mutex_t threadpool<T>::_mutex = PTHREAD_MUTEX_INITIALIZER; // 静态分配锁，无需初始化与释放 